﻿//#define SCHOOL
//#define TEST

using System;
using System.Collections.Generic;
using System.Text;

using System.Xml;
using System.Runtime.InteropServices;

using SuperMapLib;
using SDB2DM.Feature;
using SDB2DM.SpatialType;

namespace SDB2DM
{
    class DatasetNode : JPGISXML, IMainNode
    {
        Utility utl = null;
        private AxSuperMapLib.AxSuperWorkspace superWksp = null;
        private XmlNode objectNode = null;
        private string srcPath = String.Empty;
        private string destPath = String.Empty;

        public DatasetNode(XmlDocument doc, AxSuperMapLib.AxSuperWorkspace superWksp, string srcPath, string destPath)
            : base(ref doc)
        {
            this.superWksp = superWksp;
            this.srcPath = srcPath;
            this.destPath = destPath;
            utl = new Utility(superWksp, srcPath);
        }

        private void BuildXMLForCoordinate()
        {
            XmlNode rscscNode = null;
            XmlNode rsNameNode = null;
            XmlNode rsIdentifierNode = null;
            XmlNode rsIdenfifierCodeNode = null;

            for (int i = 1; i < 3; i++)
            {
                rscscNode = XMLDoc.CreateElement(
                    Utility.CM_JPS_TAG, Utility.CRDT_RS_TAG, Utility.JPS_URI);
                rsNameNode = XMLDoc.CreateElement(
                    Utility.CM_JPS_TAG, Utility.CRDT_RS_NAME_TAG, Utility.JPS_URI);
                rsIdentifierNode = XMLDoc.CreateElement(
                    Utility.CM_JPS_TAG, Utility.CRDT_IDENTIFIER_TAG, Utility.JPS_URI);
                rsIdenfifierCodeNode = XMLDoc.CreateElement(
                    Utility.CM_JPS_TAG, Utility.CRDT_IDENTIFIER_CODE_TAG, Utility.JPS_URI);

                (rscscNode as XmlElement).SetAttribute(
                    Utility.CM_ATTRIBUTE_ID_TAG, Utility.CRDT_ID_PREFIX + "0" + i.ToString());
                rsIdenfifierCodeNode.InnerText = i == 1 ? 
                    Utility.CRDT_SPATIAL_RS_VALUE : Utility.CRDT_TIME_RS_VALUE;

                objectNode.AppendChild(rscscNode);
                rscscNode.AppendChild(rsNameNode);
                rsNameNode.AppendChild(rsIdentifierNode);
                rsIdentifierNode.AppendChild(rsIdenfifierCodeNode);
            }
        }

        private void BuildSpatialData(string strFeature)
        {
            soRecordset objRS = null;
            soDatasetVector objDSV = null;

            objDSV = (soDatasetVector)utl.objSource.Datasets[strFeature];
            objRS = objDSV.Query("-1 < 0", true, null, "");

            if (!(objRS.IsBOF() && objRS.IsEOF()))
            {
                if (!objRS.IsBOF())
                {
                    objRS.MoveFirst();
                }

                ISpatial spatial = null;
                switch (objRS.GetGeometry().Type)
                {
                    case seGeometryType.scgPoint:

                        soGeoPoint objPoint = null;
                        spatial = new Point(XMLDoc, objectNode, strFeature);
                        for (; !objRS.IsEOF(); objRS.MoveNext())
                        {
                            objPoint = (soGeoPoint)objRS.GetGeometry();
                            //BuildXMLForSpatialSchema(objPoint.x, objPoint.y, strFeature);
                            spatial.BuildXMLForSpatialSchema(objPoint as soGeometry);
                        }

                        Marshal.ReleaseComObject(objPoint);
                        objPoint = null;

                        break;

                    case seGeometryType.scgLine:

                        soGeoLine objLine = null;
                        spatial = new Curve(XMLDoc, objectNode, strFeature);
                        for (; !objRS.IsEOF(); objRS.MoveNext())
                        {
                            objLine = (soGeoLine)objRS.GetGeometry();
                            spatial.BuildXMLForSpatialSchema(objLine as soGeometry);
                        }

                        Marshal.ReleaseComObject(objLine);
                        objLine = null;

                        break;

                    case seGeometryType.scgRegion:

                        soGeoRegion objRegion = null;
                        spatial = new Surface(XMLDoc, objectNode, strFeature);
                        for (; !objRS.IsEOF(); objRS.MoveNext())
                        {
                            objRegion = (soGeoRegion)objRS.GetGeometry();
                            spatial.BuildXMLForSpatialSchema(objRegion as soGeometry);
                        }

                        Marshal.ReleaseComObject(objRegion);
                        objRegion = null;

                        break;

                    default:
                        break;
                }
            }

            Marshal.ReleaseComObject(objRS);
            objRS = null;
            Marshal.ReleaseComObject(objDSV);
            objDSV = null;
        }
        
        private void BuildXMLForSpatialRSDefine(XmlNode datasetNode)
        {
            XmlNode spatialRSNode = null;

            for (int i = 1; i < 3; i++)
            {
                spatialRSNode = XMLDoc.CreateElement(
                    Utility.CM_DOMAIN_TAG, Utility.SPATIAL_REF_DEF_TAG, Utility.CM_SCHEMA_URI);
                (spatialRSNode as XmlElement).SetAttribute(
                    Utility.CM_ATTRIBUTE_IDREF_TAG, Utility.CRDT_ID_PREFIX + "0" + i.ToString());
                datasetNode.AppendChild(spatialRSNode);
            }
        }

        #region IMainNode メンバ

        public void BuildNode(XmlNode GINode)
        {
            BuildDatasetNode(GINode);
        }

        public void BuildDatasetNode(XmlNode GINode)
        {
            XmlNode datasetNode = null;
            XmlNode datasetNode1 = null;
            XmlComment xmlCmt = null;
            IFeature feature = null;

            datasetNode = XMLDoc.CreateElement(Utility.CM_LEVEL_DATASET_TAG);
            datasetNode1 = XMLDoc.CreateElement(
                Utility.CM_DOMAIN_TAG, Utility.CM_LEVEL_DATASET_TAG, Utility.CM_SCHEMA_URI);
            objectNode = XMLDoc.CreateElement(
                Utility.CM_DOMAIN_TAG,
                Utility.CM_LEVEL_DATASET_TAG + "." + Utility.CM_LEVEL_OBJECT_TAG,
                Utility.CM_SCHEMA_URI);

            GINode.AppendChild(datasetNode);
            datasetNode.AppendChild(datasetNode1);
            datasetNode1.AppendChild(objectNode);

            //座標参照系
            BuildComment(objectNode, xmlCmt, Utility.CRDT_RS_COMMENT);
            BuildXMLForCoordinate();
            //空間データ
            BuildComment(objectNode, xmlCmt, Utility.SPATIAL_COMMENT);
#if TEST
            BuildSpatialData(Utility.FEATURE_HOSPITAL);
#if SCHOOL
            BuildSpatialData(Utility.FEATURE_SCHOOL);
#endif
#else
            foreach (object obj in Utility.datasetInfo)
            {
                BuildSpatialData(obj.ToString());
                System.Windows.Forms.MessageBox.Show(obj.ToString(), "生成済み");
            }
#endif
            utl.ReleaseMemory();
            //応用データ
            BuildComment(objectNode, xmlCmt, Utility.APP_COMMENT);
            //地物
#if TEST
            /*地物 - 開始*/
            //病院
            feature = new Hospital(XMLDoc, objectNode);
            feature.BuildApplicationData();
#if SCHOOL
            //学校
            feature = new School(XMLDoc, objectNode);
            feature.BuildApplicationData();
#endif
            /*地物 - 完了*/
#else
            foreach (object obj in Utility.datasetInfo)
            {
                switch (obj.ToString())
                {
                    case Utility.FEATURE_HOSPITAL:
                        feature = new Hospital(XMLDoc, objectNode);
                        break;
                    case Utility.FEATURE_SCHOOL:
                        feature = new School(XMLDoc, objectNode);
                        break;
                }
                feature.BuildApplicationData();
            }
#endif
            //空間参照定義
            BuildComment(objectNode, xmlCmt, Utility.SPATIAL_REF_COMMENT);
            BuildXMLForSpatialRSDefine(datasetNode1);
        }

        public void BuildPortrayalNode(XmlNode GINode)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        #endregion
    }
}
